#include "cmsis_os.h"
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/sockets.h"

#include "FreeRTOS.h"
#include "task.h"
#include "MBapp.h"
#include "common.h"
#include "tcp_app.h"
#include "ethernetif.h"
#include "backup.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

static err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err);
static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static void tcp_init_para(void);
/*****************主动上传信息********************/
static uint8_t tcp_rcv_deal(struct tcp_pcb *pcb, uint8_t *puf, uint16_t len);
static uint8_t tcp_sendCmd_para(uint8_t type);
static uint8_t TcpSendHeard(void);
uint8_t sendnameBuf[6]={0}, sendnameFlag = 0;
static uint8_t TcpSendName(void);
static void TcpSendInit(void);
static uint8_t TcpSendChang(void);
static uint8_t TcpSendERR(struct tcp_pcb *pcb ,uint8_t *err);


// static uint8_t TcpClintSendInit(void);
static uint8_t TcpClintSendChang(void);
#define SEND_HEARD_NO  0
#define SEND_NAME_NO  1
#define SEND_CHANG_NO  2
Typefunc1_t conTypeFunDef[] = {

    {0X80, 0, TcpSendHeard, 2000, 0},         /*心跳信息*/
	{0X81, 0, TcpSendName, 60000, 0}, 			/*字符串信息  没有使用*/
	{0XA2, 0, TcpSendChang, 60000, 0}, 			/*参数改变信息  没有使用*/
};

/*****************设置命令********************/
static uint8_t TcpSetName(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
static uint8_t TcpSetPara(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
static uint8_t TcpSetIP(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
static uint8_t TcpREQName(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
static uint8_t TcpREQPara(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
static uint8_t TcpREQIP(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
static uint8_t TcpHeartbeat(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
static uint8_t TcpReset(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len);
//static uint8_t TcpTestBack(uint8_t *puf, uint16_t len);

TypeRcvfunc_t conTypeRcvFunDef[] = {
    {0x01, 0, TcpREQName, 0, 0},       /*请求备注*/
    {0x41, 0, TcpSetName, 0, 0},         /*设置备注*/
    {0X02, 0, TcpREQPara, 0, 0},   	/*请求数据状态*/
    {0x42, 0, TcpSetPara, 0, 0},       /*设置状态*/
	{0X03, 0, TcpREQIP, 0, 0},   	/*请求IP地址 53 4a 00 00 00 00 00 00 00 00 00 01 00 03 03*/
    {0x43, 0, TcpSetIP, 0, 0},         /*设置IP*/
	{0x04, 0, TcpReset, 0, 0},         /*复位*/
    {0X00, 0, TcpHeartbeat, 0, 0},   		/*心跳*/
};
uint32_t  sendSeq = 0;

#define SENDCMD_MAX_NUM   (sizeof(conTypeFunDef)/sizeof(Typefunc1_t))
#define RCVCMD_MAX_NUM   (sizeof(conTypeRcvFunDef)/sizeof(TypeRcvfunc_t))
#define TCP_MAX_NUM   0x400
#define TCP_ERR_CMD   0xFF
uint8_t  sendbuf[TCP_MAX_NUM] = {0}, rcvbuf[TCP_MAX_NUM] = {0}, rcvflag = 0,rcvLen;

uint8_t *ptrBuf = sendbuf;
/************************/
struct tcp_pcb *tcp_send_pcb = NULL;
void Tcp_Server_Init(void)
{
    struct tcp_pcb *tcp_server_pcb = NULL;
	  uint8_t portbuf[2];
    uint16_t  socketPort = TCP_RUN_PORT;

	  Read_Card_TcpPara(TCP_PORT_ADD, 2, portbuf);
	  socketPort = Common_bigToShort(portbuf);
    /* 为tcp分配tcp_pcb结构体 */
    tcp_server_pcb = tcp_new();

    /* 初始化IP与端口 */
    tcp_bind(tcp_server_pcb, IP_ADDR_ANY, socketPort);

    /* 监听tcp_server_pcb */
    tcp_server_pcb = tcp_listen(tcp_server_pcb);

    /* 初始化接收回调函数 */
    tcp_accept(tcp_server_pcb, tcp_server_accept);
}

/***********************************************************/
extern void tcp_find_waitPcb(void);
extern void TCPPortClose( struct tcp_pcb *pxPCB);
static err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
    /* 确定监听与连接 只允许一个客户端*/
	 if(tcp_send_pcb != NULL){
			TCPPortClose( tcp_send_pcb );
			tcp_send_pcb = NULL;
		}
    if(pcb == NULL) {
        /*网络不稳（不断插拔网线），强制释放pcb*/

        tcp_find_waitPcb();
        //#ifdef TCP_ALARM_BUG
        printf("tcp_send_pcb: accept  pcb == NULL\r\n");
        //#endif
        return ERR_ARG;
    }
		if(((uint32_t)pcb & 0x2ff00000) != 0x20000000){
				//#ifdef TCP_ALARM_BUG
				printf("tcp_send_pcb: accept  pcb ERR\r\n");
				//#endif
				tcp_find_waitPcb();
				TCPPortClose( pcb );
				return ERR_OK;
		 }
    if(tcp_send_pcb != NULL) {
       // #ifdef TCP_ALARM_BUG
        printf("tcp_send_pcb: close\r\n");
        //#endif
        tcp_close(tcp_send_pcb);
			  tcp_send_pcb = NULL;
//        tcp_close(pcb);       屏蔽减少一次再连接2020-07-10
//        return ERR_OK;
    }
    tcp_arg(pcb,  pcb);//tcp_arg(pcb, mem_calloc(sizeof(struct name), 1));
    #ifdef TCP_ALARM_BUG
    printf("tcp_alarm: accept   %0x\r\n", (uint32_t)pcb);
    #endif
    /* 接收回调与主动发送结构体赋值 */
    tcp_send_pcb = pcb;
    /* 禁止小帧数据合并，否则会出现阻塞，内存溢出错误 */
    tcp_nagle_disable(tcp_send_pcb);
    tcp_recv(pcb, tcp_server_recv);

    return ERR_OK;
}

/***接收回调函数**/
static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *tcp_recv_pbuf, err_t err)
{
    struct pbuf *tcp_send_pbuf;
#ifdef TCP_ALARM_BUG
    printf("tcp_alarm: recv  %d \r\n",sendSeq);
#endif
    if (tcp_recv_pbuf != NULL)
    {
        /* 接收数据 */
        tcp_recved(pcb, tcp_recv_pbuf->tot_len);
        /* 接收数据指针 */
        tcp_send_pbuf = tcp_recv_pbuf;
		if((0 == rcvflag) && (tcp_send_pbuf->len < TCP_MAX_NUM))
		{
			rcvLen = tcp_send_pbuf->len;
			memcpy(rcvbuf,tcp_send_pbuf->payload,tcp_send_pbuf->len);
			rcvflag = 1;
		}
//        rcvflag = 1;
//        /* 解析接收数据并应答*/
//        tcp_rcv_deal(pcb, tcp_send_pbuf->payload, tcp_send_pbuf->len);
//        rcvflag = 0;
        pbuf_free(tcp_recv_pbuf);
    }
    else if (err == ERR_OK)
    {
        /* 关闭pcb并释放内存 */
        tcp_send_pcb = NULL;
        #ifdef TCP_ALARM_BUG
        printf("tcp_alarm: close\r\n");
        #endif
        return tcp_close(pcb);
    }
    return ERR_OK;
}
/* tcp_server_thread任务 */
static uint8_t tcp503Flag = 0;
uint8_t tcp503Status(void)
{
	return tcp503Flag;
}

//#define  USER_SOCKET
#ifdef USER_SOCKET
int newsock = 0, socketErr = -1;
int ret;
void socket_rcvTick(uint16_t timeout_ms)
{
    struct timeval interval = { timeout_ms / 1000, (timeout_ms % 1000) * 1000 };
    if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0))
    {
        interval.tv_sec = 0;
        interval.tv_usec = 1000;
    }

    setsockopt(newsock, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval));
}

struct sockaddr_in address, remotehost;
void tcp_server_thread(void const*arg)
{

    int sock,  size;
	uint8_t portbuf[2];
    uint16_t  socketPort = TCP_RUN_PORT;

	  Read_Card_TcpPara(TCP_PORT_ADD, 2, portbuf);
	  socketPort = Common_bigToShort(portbuf);

    /* create a TCP socket */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        return;
    }

    /* bind to port 80 at any interface */
    address.sin_family = AF_INET;
    address.sin_port = htons(socketPort);
    address.sin_addr.s_addr = INADDR_ANY;

    if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
    {

        return;
    }
    printf("tcp_alarm:sock bind\r\n");
    /* listen for incoming connections (TCP listen backlog = 5) */
    listen(sock, 5);

    size = sizeof(remotehost);
    while(1) {
        printf("tcp_alarm:sock accept start\r\n");
        newsock = accept(sock, (struct sockaddr *)&remotehost, (socklen_t *)&size);
        printf("tcp_alarm:sock accept\r\n");
        socket_rcvTick(4);//设置接收超时
        osDelay(10);
        socketErr = 0;
        while (1)
        {
					  if(0 == netiflinkStus){//网线断了直接复位
							printf("tcp_alarm：reset\r\n");
							HAL_NVIC_SystemReset();
						}
            ret = read(newsock, rcvbuf, TCP_MAX_NUM);
            if( ret == 0 || (ret >= TCP_MAX_NUM ) || (socketErr < 0)) { //||(ret < 0 )
                printf("tcp_alarm:sock close\r\n");
								if( close( newsock ) != ERR_OK )//关一下无法立即重连？
								{
									close( newsock );
									printf("tcp_alarm:sock close faile\r\n");
								}
                break;
            }
            else if(ret < 0) {
							printf("tcp_alarm:ret < 0\r\n");
							TcpSendInit();
							tcp_sendCmd_para(1);
            }
            else if(ret > 0 && ( socketErr >=0 )) {
                tcp_rcv_deal(tcp_send_pcb, rcvbuf, ret);
            }
            osDelay(10);
        }
        osDelay(20);
    }
}
#else
//设备服务器，与平台正常通信
void tcp_server_thread( void const *argument )
{
    Tcp_Server_Init();
    // while (1)
	// {
	// 	if(tcp_send_pcb != NULL ) //&& (0 == rcvflag)
	// 	{
	// 		if(0 == rcvflag)
	// 		{
	// 			tcp503Flag = 1;
	// 			TcpSendInit();
	// 			tcp_sendCmd_para(1);
	// 		}
	// 		else{
	// 			tcp_rcv_deal(tcp_send_pcb, rcvbuf, rcvLen);
	// 			rcvflag = 0;
	// 		}
    //     }
    //     osDelay(4);
    // }
}
#endif
void clintsocket_TickOut(int socket,uint16_t timeout_ms)
{
    struct timeval interval = { timeout_ms / 1000, (timeout_ms % 1000) * 1000 };
    if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0))
    {
        interval.tv_sec = 0;
        interval.tv_usec = 1000;
    }

    setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval));
}
char server_ip_str[20]="192.168.001.248";
struct timeval timeout = {3,0};
int clintsock,clintSocketErr = 1,clintRet;
uint32_t clintTick = 0;
uint16_t  clintPort;
static uint8_t firstFlag = 0;  //第一次无论有没有卡都主动发送一次
#define CLINT_DEBUG
//设备客户端，主动与平台连接通信（参数变化主动上传）
void tcp_clint_thread( void const *argument )
{

    struct sockaddr_in send_addr;

    uint8_t str[10];
    uint8_t rtn ;


    printf("tcp_clint_thread:OK\r\n");

    /* 初始化预连接的服务端地址 */
	Read_Card_TcpPara(TCP_TRAPIP_ADD, 6, str);
	clintPort = Common_bigToShort(&str[4]);
	printf("tcp_clint_thread:IP %d.%d.%d.%d  port %d\r\n", str[0], str[1], str[2], str[3],clintPort);
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(clintPort);
	memset(server_ip_str,0,sizeof(server_ip_str));
	sprintf((char *)server_ip_str, "%d.%d.%d.%d", str[0], str[1], str[2], str[3]);
    send_addr.sin_addr.s_addr = inet_addr(server_ip_str);

    /* 创建一个 socket，类型是 SOCK_DGRAM，UDP 类型 */
    /*SOCK_STREAM => TCP*/

//		flags = fcntl(clintsock, F_GETFL, 0);//获取原始sockfd属性
//    fcntl(clintsock, F_SETFL, flags | O_NONBLOCK);//添加非阻塞
//		ioctlsocket(clintsock, FIONBIO, &imode);
    /* 总计发送 count 次数据 */
	while(1)
	{

		#ifdef  CLINT_DEBUG
		printf("tcp_clint_thread: socket...\r\n");
		#endif

		if ((clintsock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
		{
			return;
		}

		#ifdef  CLINT_DEBUG
		printf("tcp_clint_thread: connect...\r\n");
		#endif

		if (connect(clintsock, (struct sockaddr * )&send_addr, sizeof(struct sockaddr_in)) < 0)
		{
			#ifdef  CLINT_DEBUG
			printf("tcp_clint_thread: connect faile\r\n");
			#endif
			goto __exit;
		}

		clintSocketErr = 1;
		clintTick = xTaskGetTickCount();
		clintsocket_TickOut(clintsock, 4);
		#ifdef  CLINT_DEBUG
		printf("tcp_clint_thread: connect OK\r\n");
		#endif

		while (1)
		{
			/* 发送数据到服务远端 */
	//			  TcpClintSendInit();
	//        send(clintsock, send_data, strlen(send_data), 0);

			clintRet = recv(clintsock, str, sizeof(str), MSG_DONTWAIT);//MSG_DONTWAIT不等待
			if( clintRet == 0 || (clintSocketErr < 0))
			{
				#ifdef  CLINT_DEBUG
				printf("clint sock close  %d  %d\r\n",clintRet,clintSocketErr);
				#endif
	//						if(  closesocket(clintsock) != ERR_OK )//关一下无法立即重连？
	//						{
	//							 closesocket(clintsock);;
	//							 printf("clint sock close faile\r\n");
	//						}
				break;
			}

	//

			if(xTaskGetTickCount() - clintTick > TICK_M(1))//1分钟无数据变化
			{
				break;
			}
		
			if(0 == rcvflag)
			{
				TcpClintSendChang();
			}
			osDelay(4);
		}
	__exit:
    /* 关闭这个 socket */
		osDelay(400);
		closesocket(clintsock);
		osDelay(40);
	}
}
/* 创建任务 */
osThreadId AlarmTaskHandle;
osThreadId AlarmTaskHandle2;
void tcp_server_APP(void)
{

	  tcp_init_para();
    osThreadDef(AlarmTask, tcp_server_thread, osPriorityAboveNormal, 0, 256);
    AlarmTaskHandle = osThreadCreate(osThread(AlarmTask), NULL);

	//   osThreadDef(AlarmTask2, tcp_clint_thread, osPriorityAboveNormal, 0, 256);
    // AlarmTaskHandle2 = osThreadCreate(osThread(AlarmTask2), NULL);
}

static void tcp_init_para(void)
{
	  uint8_t i,index,puf[16];

	  index = 0;
	  for(i=0;i<SENDCMD_MAX_NUM;i++){
			conTypeFunDef[i].Intervaltime = (puf[index] << 8) + puf[index + 1];
			index += 2;
		}
}
#define TCP_FRAME_HEAD1         'S'
#define TCP_FRAME_HEAD2         'J'
#define TCP_HEAD_LEN            14
#define TCP_FRAME_CMD_ADD       14
#define TCP_FRAME_CRCH_ADD      12
#define TCP_FRAME_CRCL_ADD      13
#define TCP_FRAME_LEN_ADD       10  //长度地址
#define TCP_FRAME_HEAD_LEN      12  //不包括CRC
#define TCP_FRAME_DATA_ADD     15
/**4d 59 00 00 00 00 00 0d 00 00 00 19 80 b2 ff 01 00 02 00 04 00 08 00*/
 uint16_t checkSum, checkSum1,dataLen;
static uint8_t tcp_rcv_deal(struct tcp_pcb *pcb, uint8_t *puf, uint16_t len)
{
    uint8_t i;
    uint8_t errPara[2] = {0};
    TypeRcvfunc_t *TypeRcvitem = &conTypeRcvFunDef[0];

    if(len <= TCP_HEAD_LEN) {
			errPara[0] = 1;
			TcpSendERR(pcb ,errPara);
        return 0;
    }
		dataLen = (puf[TCP_FRAME_LEN_ADD]<<8) + puf[TCP_FRAME_LEN_ADD+1] + TCP_HEAD_LEN;
    checkSum = (puf[TCP_FRAME_CRCH_ADD] << 8) + puf[TCP_FRAME_CRCL_ADD];
    checkSum1 = Common_CalculateSum((uint8_t*)&puf[TCP_HEAD_LEN], (len-TCP_HEAD_LEN));
    if((checkSum == checkSum1) && (dataLen == len)) {
        for(i = 0; i < RCVCMD_MAX_NUM; i++) {
            TypeRcvitem = &conTypeRcvFunDef[i];
            if(TypeRcvitem->type == puf[TCP_FRAME_CMD_ADD]) {
                TypeRcvitem->func(pcb,puf, len);
                break;
            }
        }
        if(i>=RCVCMD_MAX_NUM){
					errPara[0] = 2;
					TcpSendERR(pcb ,errPara);
				}
    }
		else{
			errPara[0] = 3;
			errPara[1] = (checkSum != checkSum1)? 0 : 1;
			TcpSendERR(pcb ,errPara);
		}

    return 0;
}

/*******************自动上传数据*********************/
static uint8_t tcp_sendCmd_para(uint8_t type)
{
    err_t err;
    static uint8_t next = 0, errcnt;
    uint8_t i, rtn;
    Typefunc1_t *Typeitem = &conTypeFunDef[0];

    rtn = 0;
    for( i = 0 ; i < SENDCMD_MAX_NUM; i++ ) {
        next ++;
        next = (next < SENDCMD_MAX_NUM) ? next : 0;
        Typeitem = &conTypeFunDef[next];
        if(((uint32_t)(xTaskGetTickCount()-Typeitem->sendTick) > Typeitem->Intervaltime && Typeitem->Intervaltime) || Typeitem->interrut)
		{
			//作为服务器只主动上传字符串
			if((Typeitem->type != 0xA2) && (Typeitem->type != 0x80))
			{
				rtn = Typeitem->func();
				break;
			}

        }
    }
    /* 符合发送要求 */
    if(rtn) {
			#ifdef USER_SOCKET
        socketErr = send(newsock,  sendbuf, rtn, 0);
        if(socketErr < 0) {
            printf("tcp_alarm:sock send %0x\r\n", socketErr);
        }
				sendSeq++;
        Typeitem->interrut = 0;
				Typeitem->sendTick = xTaskGetTickCount();
      #else
        err = tcp_write(tcp_send_pcb, sendbuf, rtn, 1);
        if(err == ERR_OK)
		{
					( void )tcp_output( tcp_send_pcb );
            errcnt = 0;
            sendSeq++;
            Typeitem->interrut = 0;
            Typeitem->sendTick = xTaskGetTickCount();
        }
        else
		{
            if(errcnt < 10)
			{
                errcnt++;
            }
            else
			{
                tcp_close(tcp_send_pcb);
                tcp_send_pcb = NULL;
            }
            #ifdef TCP_ALARM_BUG
            printf("tcp_alarm: send faile  %d   %0x\r\n", errcnt, sendSeq);
            #endif
            next = (0 == next) ? (SENDCMD_MAX_NUM - 1) : (next - 1);
        }
				#endif
    }
    return 0;
}

//心跳包
static uint8_t TcpSendHeard(void)
{
	err_t err;
	uint8_t index;
    uint16_t checkSum;

    index = 0;
    /* 帧头 */
    ptrBuf[index++] = TCP_FRAME_HEAD1;
    ptrBuf[index++] = TCP_FRAME_HEAD2;
    ptrBuf[index++] = 0x01;
    ptrBuf[index++] = 0x00;
    Common_bigIntTo(&ptrBuf[index], sendSeq);
    index += 10;
	ptrBuf[index++] = 0x80;
    /* 长度与校验 */
	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum & 0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum >> 8) & 0x0ff;
    #ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(tcp_send_pcb, &ptrBuf[0], TCP_HEAD_LEN+1, 1);
	if(err == ERR_OK) {
		( void )tcp_output( tcp_send_pcb );
	}
	#endif
    return 0;
}
/***************uint16_t转换成uint8_t******************/
//static uint8_t Tcp16To8(uint8_t *u8puff, uint16_t *u16bff, uint8_t u16Len)
//{
//    uint8_t i, u8Len;
//    for(i = 0; i < u16Len; i++)
//    {
//        u8Len = i << 1;
//        Common_bigShortTo(&u8puff[u8Len], u16bff[i]);
//    }
//    u8Len = u16Len << 1;
//    return u8Len;
//}

static uint8_t TcpSendName(void)
{
	err_t err;
  	uint16_t 	checkSum,index;
	uint8_t rbuf[ONESTR_MAX_LEN],rbuflen,rPara[4],rtn;
	uint8_t i,j,k;


    index = 0;
    /* 帧头 */
    ptrBuf[index++] = TCP_FRAME_HEAD1;
    ptrBuf[index++] = TCP_FRAME_HEAD2;
    ptrBuf[index++] = 0x01;
    ptrBuf[index++] = 0x00;
    Common_bigIntTo(&ptrBuf[index], sendSeq);
    index += 10;
	ptrBuf[index++] = 0x81;

	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(tcp_send_pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK) {
		( void )tcp_output( tcp_send_pcb );
	}
	#endif
	return 0;
}
/************发送改变参数*****************/
static void TcpSendInit(void)
{
	if(sendnameFlag)
	{
		conTypeFunDef[SEND_NAME_NO].interrut = 1;
	}
	else{
		conTypeFunDef[SEND_NAME_NO].sendTick = xTaskGetTickCount();
	}

}
// static uint8_t TcpClintSendInit(void)
// {
// 	if(find_chang_Card(0, 0) < SYS_MAX_CARD){
// 		return APP_NO_CHANGE;
// 	}
// 	else{
// 		return APP_OK;
// 	}
// }

//发送参数变化数据
static uint8_t TcpSendChang(void)
{
	err_t err;
    uint8_t index, i;
    uint16_t checkSum;
    index = 0;
    /* 帧头 */
    ptrBuf[index++] = TCP_FRAME_HEAD1;
    ptrBuf[index++] = TCP_FRAME_HEAD2;
    ptrBuf[index++] = 0x01;
    ptrBuf[index++] = 0x00;
    Common_bigIntTo(&ptrBuf[index], sendSeq);
    index += 10;

    /* 长度与校验 */
	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*) & ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum & 0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum >> 8) & 0x0ff;
    #ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(tcp_send_pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK)
	{
		( void )tcp_output( tcp_send_pcb );
	}
	#endif
    return 0;
}

//主动上传有变化的参数
uint8_t TcpClintSendChang(void)
{
	static uint8_t carAdd = 0;
    uint8_t index, i;
    uint16_t checkSum;
    index = 0;
    /* 帧头 */
    ptrBuf[index++] = TCP_FRAME_HEAD1;
    ptrBuf[index++] = TCP_FRAME_HEAD2;
    ptrBuf[index++] = 0x01;
    ptrBuf[index++] = 0x00;
    Common_bigIntTo(&ptrBuf[index], sendSeq);
    index += 10;

    /* 长度与校验 */
	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum & 0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum >> 8) & 0x0ff;

	clintSocketErr = send(clintsock, &ptrBuf[0], index, 1);

    return 0;
}
static uint8_t TcpSetPara(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
	err_t err;
	uint16_t 	checkSum,index,i;

	index = 0;
	memcpy(&ptrBuf[0],puf,TCP_HEAD_LEN);
	index = index + TCP_HEAD_LEN;
	ptrBuf[TCP_FRAME_CMD_ADD]	= puf[TCP_FRAME_CMD_ADD] + 0X80	;
	index = index + 1;

	/*              begin                     */


	/*               end                    */
	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK) {
		( void )tcp_output( pcb );
	}
	#endif
  return 0;
}

//uint8_t  ddd[32]={0xAA,0x55,0x20,0x00,0x20, 0x0D, 0x01, 0x01 ,0x01, 0x01, 0x01 ,0x01 ,0x01 ,0x01, 0x01 ,0x01, 0x01, 0x01 ,0x01, 0x01 ,0x01, 0x01, 0x01 ,0x01, 0x01 ,0x01 ,0x01, 0x01, 0x01 ,0x01 ,0x35 ,0xE9};
static uint8_t TcpREQPara(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
	err_t err;
  	uint16_t 	checkSum,index;
	uint8_t i, j, reqCard, reqNum;
 // uint8_t x;
	index = 0;
	memcpy(&ptrBuf[0], puf, TCP_HEAD_LEN);

	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK) {
		( void )tcp_output( pcb );
	}
  #endif
	return 0;
}

static uint8_t TcpSetIP(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
	err_t err;
	uint8_t rPara[2];
	uint8_t tcpbuf[ONESTR_MAX_LEN],resetFlag = 0;
  	uint16_t 	checkSum,index;


	index = TCP_HEAD_LEN + 1;
	Read_Card_TcpPara(0, CARD_PARA_LEN, &tcpbuf[0]);//ip
	#ifndef TCP_SAVE_STM32
  	if(0 != memcmp(&tcpbuf[TCP_IP_ADD],&puf[index+TCP_IP_ADD],4)){
		resetFlag = 1;
		SD_Fatfs_saveIP(0, &puf[index+TCP_IP_ADD]);
	}
	if(0 != memcmp(&tcpbuf[TCP_MASK_ADD],&puf[index+TCP_MASK_ADD],4)){
		resetFlag = 1;
		SD_Fatfs_saveIP(1, &puf[index+TCP_MASK_ADD]);
	}
	if(0 != memcmp(&tcpbuf[TCP_GW_ADD],&puf[index+TCP_GW_ADD],4)){
		resetFlag = 1;
		SD_Fatfs_saveIP(2, &puf[index+TCP_GW_ADD]);
	}
	if(0 != memcmp(&tcpbuf[TCP_MAC_ADD],&puf[index+TCP_MAC_ADD],6)){
		resetFlag = 1;
		SD_Fatfs_saveIP(3, &puf[index+TCP_MAC_ADD]);
	}
	if(0 != memcmp(&tcpbuf[TCP_PORT_ADD],&puf[index+TCP_PORT_ADD],2)){
		resetFlag = 1;
		SD_Fatfs_saveIP(4, &puf[index+TCP_PORT_ADD]);
	}
	if(0 != memcmp(&tcpbuf[TCP_TRAPIP_ADD],&puf[index+TCP_TRAPIP_ADD],4)){
		resetFlag = 1;
		SD_Fatfs_saveIP(5, &puf[index+TCP_TRAPIP_ADD]);
	}
	if(0 != memcmp(&tcpbuf[TCP_TRAPPORT_ADD],&puf[index+TCP_TRAPPORT_ADD],2)){
		resetFlag = 1;
		SD_Fatfs_saveIP(6, &puf[index+TCP_TRAPPORT_ADD]);
	}
	#else
	if(0 != memcmp(&tcpbuf[0],&puf[index],(CARD_PARA_LEN-2))){ //不比较CRC
		resetFlag = SaveParaBackup(&puf[index]) + 1;
	}
	#endif
	index = 0;
	memcpy(&ptrBuf[0],puf,TCP_HEAD_LEN);
	ptrBuf[TCP_FRAME_CMD_ADD]	= puf[TCP_FRAME_CMD_ADD] + 0X80	;
	index = TCP_HEAD_LEN + 1;

	ptrBuf[index++] = resetFlag;
	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	if(socketErr<0)return 0;
	#else

	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK) {
		( void )tcp_output( pcb );
		//printf("tcp_alarm: TcpSetIP  8\r\n");
	}
	#endif
//	if(resetFlag){
//		osDelay(50);
//		HAL_NVIC_SystemReset();
//	}
	return 0;
}

//应答系统参数
static uint8_t TcpREQIP(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
	err_t err;
  	uint16_t 	checkSum,index;

	index = 0;
	memcpy(&ptrBuf[0],puf,TCP_HEAD_LEN);
	ptrBuf[TCP_FRAME_CMD_ADD]	= puf[TCP_FRAME_CMD_ADD] + 0X80	;
	index = TCP_HEAD_LEN + 1;
	#ifndef TCP_SAVE_STM32
	SD_Fatfs_IP_get(&ptrBuf[index]);
	#else
	Read_Card_TcpPara(0, CARD_PARA_LEN, &ptrBuf[index]);
	#endif
	index += CARD_PARA_LEN;

	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK) {
		( void )tcp_output( pcb );
	}
	#endif
	return 0;
}

//处理平台发送复位指令
static uint8_t TcpReset(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
	err_t err;
  	uint16_t 	checkSum,index;

	index = 0;
	memcpy(&ptrBuf[0], puf, TCP_HEAD_LEN);
	ptrBuf[TCP_FRAME_CMD_ADD] = puf[TCP_FRAME_CMD_ADD] + 0X80	;
	index = TCP_HEAD_LEN + 1;

	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum & 0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum >> 8) & 0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK) {
		( void )tcp_output( pcb );
	}
	#endif
	osDelay(100);
	HAL_NVIC_SystemReset();
	return 0;
}

//平台下发字符串
static uint8_t TcpSetName(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
	err_t err;
	uint8_t sbuf[ONESTR_MAX_LEN],slen,alllen,nowi;
  	uint16_t checkSum,index,i;

	index = 0;
	memcpy(&ptrBuf[0],puf,TCP_HEAD_LEN);
	ptrBuf[TCP_FRAME_CMD_ADD]	= puf[TCP_FRAME_CMD_ADD] + 0X80	;
	index = TCP_HEAD_LEN + 1;


	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum & 0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum >> 8) & 0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK)
	{
		( void )tcp_output( pcb );
	}
	#endif
	return 0;
}

//平台请求字符串应答
static uint8_t TcpREQName(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
	err_t err;
  	uint16_t checkSum,index;
	uint8_t rbuf[ONESTR_MAX_LEN], rbuflen, reqCmd[4], rPara[4], rtn;
	uint8_t i, j, k;

	index = 0;
	memcpy(&ptrBuf[0], puf, TCP_HEAD_LEN);
	ptrBuf[TCP_FRAME_CMD_ADD] = puf[TCP_FRAME_CMD_ADD] + 0X80;
	index = TCP_HEAD_LEN + 1;

	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK)
	{
		( void )tcp_output( pcb );
	}
	#endif
	return 0;
}
/* 错误 */
static uint8_t TcpSendERR(struct tcp_pcb *pcb ,uint8_t *err)
{
	err_t err1;
  	uint16_t 	checkSum,index;

	index = 0;
	/* 帧头 */
	ptrBuf[index++] = TCP_FRAME_HEAD1;
	ptrBuf[index++] = TCP_FRAME_HEAD2;
	ptrBuf[index++] = 0x00;
	ptrBuf[index++] = 0x00;
	Common_bigShortTo(&ptrBuf[index], sendSeq);
	index += 10;

	ptrBuf[TCP_FRAME_CMD_ADD]	= TCP_ERR_CMD	;
	index = TCP_HEAD_LEN + 1;
	ptrBuf[index++] = err[0];
	ptrBuf[index++] = err[1];
	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err1 = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err1 == ERR_OK) {
		 sendSeq++;
		( void )tcp_output( pcb );
	}

	#endif
	return 0;
}
/* 回应心跳 */
static uint8_t TcpHeartbeat(struct tcp_pcb *pcb,uint8_t *puf, uint16_t len)
{
  err_t err;
  uint16_t 	checkSum,index;

	index = 0;
	memcpy(&ptrBuf[0],puf,TCP_HEAD_LEN);
	ptrBuf[TCP_FRAME_CMD_ADD]	= puf[TCP_FRAME_CMD_ADD] + 0X80	;
	index = TCP_HEAD_LEN + 1;

	Common_bigShortTo(&ptrBuf[TCP_FRAME_LEN_ADD], (index - TCP_HEAD_LEN));
	checkSum = Common_CalculateSum((uint8_t*)&ptrBuf[TCP_HEAD_LEN], (index - TCP_HEAD_LEN));
	ptrBuf[TCP_FRAME_CRCL_ADD] = checkSum&0x0ff;
	ptrBuf[TCP_FRAME_CRCH_ADD] = (checkSum>>8)&0x0ff;
	#ifdef USER_SOCKET
	socketErr = send(newsock, &ptrBuf[0], index, 1);
	#else
	err = tcp_write(pcb, &ptrBuf[0], index, 1);
	if(err == ERR_OK) {
		( void )tcp_output( pcb );
	}
	#endif
	return 0;
}

